package com.xiyu.service.service.fee;

import com.xiyu.service.vo.fee.feeCategory.FeeCategoryGetByTypeOutput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryListQueryOutput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryGetFirstFeeOutput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryGetOutput;
import com.xiyu.service.model.fee.category.FeeCategory;
import com.xiyu.service.repository.fee.category.FeeCategoryRepository;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryUpdateInput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryCreateInput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryQueryOutput;
import com.xiyu.service.vo.fee.feeCategory.FeeCategoryQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.fee.FeeCategoryConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.fee.FeeCategoryErrorCode.*;

/**
 * 费用类别 Service 实现类
 */
@Service
@Validated
public class FeeCategoryServiceImpl implements FeeCategoryService {

    @Resource
    private FeeCategoryRepository feeCategoryRepository;

    @Override
    public PageResult<FeeCategoryQueryOutput> query(FeeCategoryQueryInput inputVO) {
        Page<FeeCategory> categoryPage = feeCategoryRepository.pageQuery(inputVO);
        List<FeeCategoryQueryOutput> categoryList = FeeCategoryConvert.INSTANCE.queryPageOutputConvert(categoryPage.getRows());
        return new PageResult<>(categoryList, categoryPage.getTotalRowCount());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(FeeCategoryCreateInput inputVO) {
        Optional<FeeCategory> opDupCategory = feeCategoryRepository.findFirstByCategoryName(inputVO.getCategoryName());
        if(opDupCategory.isPresent()){
            throw exception(FEE_CATEGORY_EXISTS);
        }
        FeeCategory newCategory = FeeCategoryConvert.INSTANCE.createInputConvert(inputVO);
        newCategory = feeCategoryRepository.insert(newCategory);
        return newCategory.id();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(FeeCategoryUpdateInput inputVO) {
        Optional<FeeCategory> opDupCategory = feeCategoryRepository.findFirstByCategoryNameAndIdNot(inputVO.getCategoryName(), inputVO.getId());
        if(opDupCategory.isPresent()){
            throw exception(FEE_CATEGORY_EXISTS);
        }
        FeeCategory updateCategory = FeeCategoryConvert.INSTANCE.updateInputConvert(inputVO);
        feeCategoryRepository.update(updateCategory);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleted(Long id) {
        Optional<FeeCategory> opDeleteCategory = feeCategoryRepository.findById(id);
        if(!opDeleteCategory.isPresent()){
            throw exception(FEE_CATEGORY_NOT_EXISTS);
        }
        if(opDeleteCategory.get().isBuiltin()){
            throw exception(FEE_CATEGORY_NOT_DELETE);
        }
        feeCategoryRepository.deleteById(id);
        return true;
    }

    @Override
    public FeeCategoryGetOutput get(Long id) {
        Optional<FeeCategory> opCategory = feeCategoryRepository.findById(id);
        if(!opCategory.isPresent()){
            throw exception(FEE_CATEGORY_NOT_EXISTS);
        }
        return FeeCategoryConvert.INSTANCE.getOutputConvert(opCategory.get());
    }

    @Override
    public List<FeeCategoryGetFirstFeeOutput> getFirstFee() {
        List<FeeCategory> feeCategoryList = feeCategoryRepository.findByIsFirst(true);
        return FeeCategoryConvert.INSTANCE.getFirstFeeOutputConvert(feeCategoryList);
    }

    @Override
    public List<FeeCategoryListQueryOutput> listQuery() {
        List<FeeCategory> listFeeCategory = feeCategoryRepository.listQuery();
        return FeeCategoryConvert.INSTANCE.listQueryOutputConvert(listFeeCategory);

    }

    @Override
    public List<FeeCategoryGetByTypeOutput> getByType(Integer type) {
        List<FeeCategory> feeCategoryList = feeCategoryRepository.findByType(type);
        return FeeCategoryConvert.INSTANCE.getByTypeOutputConvert(feeCategoryList);
    }

}
